/*
 * tlineDAO.java
 *
 * Created on March 17, 2007, 2:14 PM
 */

package edu.byu.isys413.mystuff;

import java.util.*;
import java.sql.*;

/**
 *
 * @author Sam Griffiths
 */
public class tlineDAO {
    
    //initialize variables
    private static tlineDAO instance;
    private String tlineid;
    private static Cache cache;
    
    /** Creates a new instance of tlineDAO */
    public tlineDAO() {
    cache = Cache.getInstance();
    }
     
    //returns an instance
    public static synchronized tlineDAO getInstance() {
        if (instance == null) {
            instance = new tlineDAO();
        }
        return instance;
    }
    
    //creates a new tlineBO with the id initialized
    public tlineBO create(){
        tlineid = Guid.generate();
        tlineBO tline = new tlineBO(tlineid);
        cache.put(tlineid, tline);
        return tline;
    }
    
    /*
     *This method reads all tline BO's from the database and returns them in an ArrayList
     */
    public synchronized ArrayList<tlineBO> readALL() throws DataException {
        ArrayList<tlineBO> tlinelist = new ArrayList();
        Connection conn = null;
        try {
            //retrieve connection, create a statement, execute query
            conn = ConnectionPool.getInstance().get();
            //System.out.println("Check");
            Statement st = conn.createStatement();
            //System.out.println("Executing Query");
            ResultSet rs = st.executeQuery("SELECT * FROM TRANSLINE_TABLE");
            //System.out.println("Execute Succesful");
            
            //use result set to cycle throuh, create and intialize bos and add them to the arraylist respectively
            while(rs.next()){
                tlineBO tline = new tlineBO(rs.getString("TRANSLID"));
                tline.setTransactionId(rs.getString("TRANSACID"));//artist
                tline.setRevSource(rs.getString("REVID"));//album
                tline.setAlreadyInDatabase(true);
                tlinelist.add(tline);
            }
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return tlinelist;
    }
    
    //Creates a connection and calls another read and returns the bo of the id handed in
    public synchronized tlineBO read(String tlineid) throws DataException{
        tlineBO str = null;
        Connection conn = null;
        try {
            conn = ConnectionPool.getInstance().get();
            if(cache.containsKey(tlineid))
                str = (tlineBO)cache.get(tlineid);
            else
                str = read(conn, tlineid);
            
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return str;
    }
    
    //exactly 
    public synchronized tlineBO read(Connection conn, String id){
       tlineBO tline = null;
        try{
        Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM TRANSLINE_TABLE WHERE TRANSLID='"+id+"'");
            tline = new tlineBO(id);
            while(rs.next()){
                tline.setTransactionId(rs.getString("TRANSACID"));//artist
                tline.setRevSource(rs.getString("REVID"));//album
                tline.setAlreadyInDatabase(true);
                            
            }
       }catch(Exception e){}
       cache.put(id, tline);
       return tline;
    }
    
    /////////////save////////////////////
    //calls second save after getting a connection and hands in bo and connection
    public synchronized boolean save(tlineBO bo) throws DataException {
       System.out.println("Save entrance accessed");
        Connection conn = null;
        try {
            
            conn = ConnectionPool.getInstance().get();
            if(bo.isDirty())
                save(conn,bo);
            bo.setDirty(false);
            
            if(bo.getRevenueSource()!=null){
                revDAO rd = revDAO.getInstance();
                rd.save(conn, bo.getRevenueSource());
            }
            if(bo.getCoupon()!=null){
                couponDAO cd = couponDAO.getInstance();
                cd.save(conn, bo.getCoupon());
            }
                
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return true;
        }
    
    //Checks if bo is already in database, if yes then create 
    public synchronized void save(Connection conn, tlineBO bo){
        System.out.println("Second Save Accessed");
        try{
            Statement st = conn.createStatement();
            String tlineid = "";
           
            System.out.println("First Query Skipped");
            if(false == bo.isAlreadyInDatabase()){
                
                String queryString = "INSERT INTO TRANSLINE_TABLE VALUES (?,?,?)";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
               
                //String aString = Double.toString(aDouble);
                pstmt.setString(1,bo.getTransactionLineId());
                pstmt.setString(2,bo.getTransactionId());
                pstmt.setString(3,bo.getRevSource());
                pstmt.execute();
                pstmt.close();
                bo.setAlreadyInDatabase(true);
            } else{
            
                String queryString = "UPDATE TRANSLINE_TABLE SET TRANACID = ?, REVID = ? WHERE TRANSLID = ? ";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
                pstmt.setString(1,bo.getTransactionId());
                pstmt.setString(2,bo.getRevSource());
                pstmt.setString(3,bo.getTransactionLineId());
                pstmt.execute();
                pstmt.close();
                
            }
        }catch(Exception e){}
    }
    
    /////////////delete////////////////////////
    /*
        We're assuming we will never need to delete a store, if a faulty one is made we can just set it update it 
     *  to an actual new store. No problems, We shouldn't be deleting stores, anyways.
     */
    
}
